package com.cby.operation.pay.core

import android.app.Activity
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.TextUtils
import com.cby.operation.common.ext.showToast
import com.cby.operation.common.ui.UIStackManager
import com.cby.operation.common.util.CbyLogUtils
import com.cby.operation.common.util.HandlerUtils
import com.cby.operation.common.util.NetworkUtils
import com.cby.operation.login.LoginManager
import com.cby.operation.login.data.InternalUser
import com.cby.operation.pay.PayManager
import com.cby.operation.pay.bean.*
import com.cby.operation.pay.channel.PayResultCallBack
import com.cby.operation.pay.channel.PayWrapper
import com.cby.operation.pay.channel.alipay.AlipayWrapper
import com.cby.operation.pay.channel.wechat.WechatPayWrapper
import com.cby.operation.pay.data.PayApiRepository
import com.cby.operation.pay.data.PayLogApiRepository
import com.cby.operation.sdk.*
import java.lang.ref.WeakReference

/**
 * @description: PayEngine
 *
 * @author ChenBaoyang
 * @date 8/7/21 15:29
 */
class PayEngine(private val activity: Activity, private val payInfo: PayInfo) {



    private var orderId: String? = null
    private var payChannel: String? = null
    private var payWrapper: PayWrapper? = null

    private lateinit var callbackReference: WeakReference<CallBack>

    private var count: Int= 0

    private var needOrderQuery = false
    private var isFromBackGround = false

    /**
     * 下单
     *
     * @param payChannel 支付渠道信息[PayChannel]
     * @param callBack OnPayResult
     */
    fun submitOrder(payChannel: PayChannel, callBack: CallBack) {
        callbackReference = WeakReference(callBack)
        val user: InternalUser = LoginManager.instance.getUser() ?: return
        
        //服务端下单操作，获取三方支付的相关配置
        PayApiRepository.submitOrder(
            payInfo.cpOrderId!!, user.nick!!, payInfo.money,
            payInfo.goodsName!!, payInfo.server, payInfo.ext, payChannel.payChannelValue,
            object : PayApiRepository.OnSubmitOrderCallBack {
                override fun onResponseOk(orderInfo: PayOrderInfo?) {
                    orderId = orderInfo!!.orderId
                    HandlerUtils.runOnMainThread { openThirdPartyPay(orderInfo) }
                }

                override fun onPayLimit(payLimit: PayLimit?) {
                    HandlerUtils.runOnMainThread {
                        UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_PAY_SUBMIT)
                    }
                    PayManager.instance.showPayLimitDialog(payLimit, payInfo)
                }

                override fun onResponseFailed(code: Int, message: String?) {
                    if (code == CODE_USER_ROBBED) {
                        if (message != null) {
                            PayManager.instance.handleUserRobbed(message)
                        }
                        UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_PAY_SUBMIT)
                    } else {
                        HandlerUtils.runOnMainThread {
                            if (NetworkUtils.isConnected(activity)) {
                                val result = PayResult()
                                result.payInfo = payInfo
                                result.resultCode = code
                                result.message = message
                                PayManager.instance.handlePayCallBack(result)
                                activity.showToast(message.toString())
                                UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_PAY_SUBMIT)
                            } else {
                                activity.showToast(ERR_MSG_NETWORK_ERROR)
                            }
                        }
                    }
                }
            })
        

    }

    /**
     * 处理
     *
     * @param status String
     * @param resultInfo String?
     */
    private fun handleCallBack(status: String?, resultInfo: String?) {
        callbackReference.get()?.onResult(status, resultInfo)
    }

    /**
     * 打开第三方支付
     *
     * @param orderInfo 订单信息[PayOrderInfo]
     */
    private fun openThirdPartyPay(orderInfo: PayOrderInfo) {
        payChannel = orderInfo.payType
        if (TextUtils.equals(orderInfo.payType, VALUE_PAY_CHANNEL_WECHAT_H5)) {
            payWrapper = WechatPayWrapper()
        } else if (TextUtils.equals(orderInfo.payType, VALUE_PAY_CHANNEL_ALIPAY)
        ) {
            payWrapper = AlipayWrapper()
        }

        //下单，打开第三方支付的时候，置为true
        isFromBackGround = true
        if (payWrapper != null) {
            payWrapper!!.doPay(activity, orderInfo, object : PayResultCallBack {
                override fun onResult(success: Boolean, status: String?, resultInfo: String?) {
                    //暂时做个判断处理, 提交中，需要SDK去做轮询查询订单
                    if (TextUtils.equals(status, WechatPayWrapper.HYKB_WECHATH5_CODE_SUBMIT)) {
                        handleCallBack(status, resultInfo)
                        needOrderQuery = true
                        startPollingOrder()
                        return
                    }
                    // 直接支付成功，返回
                    handlePayResult(status!!.toInt(), resultInfo)
                }
            })
        }
    }

    fun checkOrder() {
        if (needOrderQuery && isFromBackGround) {
            needOrderQuery = false
            //开始轮询查订单
            count = 0
            startPollingOrder()
        }
    }

    private fun startPollingOrder() {
        handler.removeMessages(MSG_POLLING)
        handler.sendEmptyMessageDelayed(MSG_POLLING, POLLING_INTERVAL.toLong())
    }

    private val handler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            if (msg.what == MSG_POLLING && count < POLLING_MAX_TIME) {
                doWork()
                count++
                CbyLogUtils.flog("count = $count")
            }
        }
    }

    private fun doWork() {
        PayApiRepository.orderQuery(orderId!!, object : PayApiRepository.OnOrderQueryCallBack {
            override fun onResponse(code: Int, msg: String?) {
                if (code == CODE_ORDER_NOT_FIND && count < POLLING_MAX_TIME) {
                    //继续查询
                    handler.sendEmptyMessageDelayed(
                        MSG_POLLING,
                        POLLING_INTERVAL.toLong()
                    )
                } else {
                    //次数置为最大，介绍轮询，相应订单结果给玩家
                    count = POLLING_MAX_TIME
                    if (code != CODE_SUCCESS) {
                        //支付不成功的话，重置轮询的状态
                        needOrderQuery = true
                    }
                    //这边将支付成功的code强制转为9000
                    handlePayResult(if (code == CODE_SUCCESS) 9000 else code, msg)
                }
            }
        })
    }


    /**
     * 支付结果返回
     *
     * @param code          支付结果code
     * @param resultInfo    支付结果提示内容
     */
    private fun handlePayResult(code: Int, resultInfo: String?) {
        //支付结果日志上报
        payResultReport(code, resultInfo)
        val result = PayResult()
        result.payInfo = payInfo
        result.resultCode = code
        result.message = resultInfo
        result.payChannel = payChannel
        result.orderId = orderId
        PayManager.instance.showPayResultDialog(result)
        UIStackManager.instance!!.finishFragment(TAG_FRAGMENT_PAY_SUBMIT)
    }

    /**
     * 日志上报
     *
     * @param code 支付结果code
     * @param msg  支付结果信息
     */
    private fun payResultReport(code: Int, msg: String?) {
        val content = if (code == CODE_SUCCESS) "ok" else msg!!
        PayLogApiRepository.payReport(orderId!!, content)
    }


    companion object{
        /**
         * handler消息
         */
        private const val MSG_POLLING = 101

        /**
         * 轮询间隔
         */
        private const val POLLING_INTERVAL = 1000

        /**
         * 轮询的最大次数
         */
        private const val POLLING_MAX_TIME = 5
    }


    interface CallBack {

        fun onResult(status: String?, resultInfo: String?)
    }
}